﻿using BITUI.Tile;
using SDL2;
using System;
using System.Collections.Generic;
using System.Text;

namespace BITUI.Element
{
    //Canvas 具有Fill属性
    //有Fill属性的对象，可以自己在父容器的范围内填充
    //四个边距分别是TileX,TileY,TileBorderRight,TileBorderBottom
    public class Canvas : IElement2DGroup
    {
        List<IElement2D> _children = new List<IElement2D>();
        public IFillDraw backGround;
        public byte backGroundColorReplace = 0;
        public int clipBorderPixel = 0;
        public IReadOnlyList<IElement2D> children
        {
            get
            {
                return _children.AsReadOnly();
            }
        }
        public IElement2DGroup Parent
        {
            get;
            internal set;
        }
        void IElement2D.SetParent(IElement2DGroup parent)
        {
            this.Parent = parent;
        }

        public int TileXLocal
        {
            get;
            set;
        }

        public int TileYLocal
        {
            get;
            set;
        }
        public int TileX
        {
            get
            {
                if (this.Parent != null)
                    return this.Parent.TileX + this.TileXLocal;
                else
                    return this.TileXLocal;
            }
        }

        public int TileY
        {
            get
            {
                if (this.Parent != null)
                    return this.Parent.TileY + this.TileYLocal;
                else
                    return this.TileYLocal;
            }
        }
        public bool Fill
        {
            get;
            set;
        } = true;
        public int BorderRightLocal
        {
            get;
            set;
        }
        public int BorderBottomLocal
        {
            get;
            set;
        }
        public int TileWidth
        {
            get;
            set;
        }
        public int TileHeight
        {
            get;
            set;
        }


        public virtual void AddChild(IElement2D element)
        {
            if (_children.Contains(element)) return;
            if (element.Parent != null)
                element.Parent.RemoveChild(element);
            _children.Add(element);
            element.SetParent(this);
            if (element is IElement2DGroup)
                (element as IElement2DGroup).OnParentResize(this.TileWidth, this.TileHeight);
        }

        public virtual void OnDraw(IWindowRender render)
        {
            if (backGround != null)
            {
                backGround.FillDraw(render, this.TileX * 8, this.TileY * 8, this.TileWidth * 8, this.TileHeight * 8, backGroundColorReplace);
            }
            int x1 = this.TileX * 8 + clipBorderPixel;
            int y1 = this.TileY * 8 + clipBorderPixel;
            int x2 = (this.TileX + this.TileWidth) * 8 - clipBorderPixel;
            int y2 = (this.TileY + this.TileHeight) * 8 - clipBorderPixel;
            render.PushLimitTileRect(new LimitRect { xmin = x1, ymin = y1, xmax = x2, ymax = y2 });

            foreach (var c in _children)
            {
                c.OnDraw(render);
            }
            render.PopLimitTileRect();

        }
        public virtual void OnParentResize(int TileWidth, int TileHeight)
        {
            if (this.Fill)
            {
                this.TileWidth = TileWidth - this.TileXLocal - this.BorderRightLocal;
                this.TileHeight = TileHeight - this.TileYLocal - this.BorderBottomLocal;
            }
            foreach (var c in _children)
            {
                var group = c as IElement2DGroup;
                if (group != null)
                    group.OnParentResize(this.TileWidth, this.TileHeight);
            }
        }
        public virtual void RemoveChild(IElement2D element)
        {
            if (_children.Remove(element))
            {
                element.SetParent(null);
            }
        }

        //向下传
        bool IElementWithEvent.OnMouseDown(IWindowEvent win, byte button)
        {
            for (var i = this._children.Count - 1; i >= 0; i--)
            {
                var se = this._children[i] as IElementWithEvent;
                if (se != null)
                {
                    var b = se.OnMouseDown(win, button);
                    if (!b) return false;
                }
            }
            return true;
        }


        //向下传
        bool IElementWithEvent.OnMouseMove(IWindowEvent win, int x, int y)
        {
            for (var i = this._children.Count - 1; i >= 0; i--)
            {
                var se = this._children[i] as IElementWithEvent;
                if (se != null)
                {
                    var b = se.OnMouseMove(win, x, y);
                    if (!b) return false;
                }
            }
            return true;
        }
        //向上传
        bool IElementWithEvent.OnMouseWheel(IWindowEvent win, uint dir, int x, int y)
        {
            if (this.Parent != null)
            {
                var b = Parent.OnMouseWheel(win, dir, x, y);
                if (!b) return false;
            }
            return true;
        }
        //不会收到
        void IElementWithEvent.OnMouseUp(IWindowEvent win, byte button)
        {
        }
        //不会收到
        void IElementWithEvent.OnInput(IWindowEvent win, string text)
        {
        }
        //不会收到
        void IElementWithEvent.OnMouseLeave(IWindowEvent win)
        {
        }
        //不会收到
        void IElementWithEvent.OnLostFocus(IWindowEvent win)
        {
        }

        public void OnKey(IWindowEvent win, SDL.SDL_Scancode key, bool press)
        {
        }
    }
}
